package org.zjx.operate;

import lombok.SneakyThrows;
import org.zjx.entity.Rect;

import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;

public class RobotOperate implements IOperate {
    public static final int MOUSE_LEFT = InputEvent.BUTTON1_MASK;
    public static final int MOUSE_RIGHT = InputEvent.BUTTON3_MASK;

    // 单例实例（volatile 保证可见性）
    private static volatile RobotOperate instance;
    private final Robot robot;

    // 私有构造方法
    private RobotOperate() throws AWTException {
        this.robot = new Robot();
    }

    // 获取单例（双重校验锁，线程安全）
    public static RobotOperate getInstance() {
        if (instance == null) {
            synchronized (RobotOperate.class) {
                if (instance == null) {
                    try {
                        instance = new RobotOperate();
                    } catch (AWTException e) {
                        throw new RuntimeException("初始化 Robot 失败", e);
                    }
                }
            }
        }
        return instance;
    }


    @SneakyThrows
    @Override
    public BufferedImage getImage(Rect rect) {
        // 获取原始的屏幕截图（默认是 TYPE_INT_RGB 类型）
        BufferedImage screenCapture = robot.createScreenCapture(rect.toRectangle());

        // 创建一个新的 BufferedImage，类型为 TYPE_INT_ARGB，用于支持透明度
        BufferedImage argbImage = new BufferedImage(screenCapture.getWidth(), screenCapture.getHeight(), BufferedImage.TYPE_INT_ARGB);

        // 使用 Graphics2D 将 TYPE_INT_RGB 图像的像素数据绘制到新的 TYPE_INT_ARGB 图像上
        Graphics2D g2d = argbImage.createGraphics();
        g2d.drawImage(screenCapture, 0, 0, null);
        g2d.dispose();

        // 返回支持透明度的图像
        return argbImage;
    }

    @SneakyThrows
    @Override
    public Color getPixelColor(int x, int y) {
        return robot.getPixelColor(x, y);
    }

    @SneakyThrows
    @Override
    public void moveMouse(int x, int y) {
        robot.mouseMove(x, y);
    }

    @Override
    public void clickMouse(Point point) {
        moveMouse(point.x, point.y);
        delay(30);
        clickMouse(1);
    }

    @SneakyThrows
    @Override
    public void clickMouse(int button) {
        clickMouse(button, MouseAction.DOWN);
        clickMouse(button, MouseAction.UP);
    }

    @SneakyThrows
    @Override
    public void clickMouse(int button, MouseAction action) {
        int mouseButton = button == 1 ? MOUSE_LEFT : MOUSE_RIGHT;
        if (action == MouseAction.DOWN) {
            robot.mousePress(mouseButton);
        } else {
            robot.mouseRelease(mouseButton);
        }
    }

    @SneakyThrows
    @Override
    public void scrollMouse(int amount) {
        robot.mouseWheel(amount); // 正数表示向上滚动
    }

    @Override
    public void dragMouse(int startX, int startY, int endX, int endY) {

    }

    @SneakyThrows
    @Override
    public void write(String text) {
        for (char c : text.toCharArray()) {
            int keyCode = KeyEvent.getExtendedKeyCodeForChar(c);
            if (keyCode != KeyEvent.VK_UNDEFINED) {
                robot.keyPress(keyCode);
                robot.keyRelease(keyCode);
            }
        }
    }

    @SneakyThrows
    @Override
    public void pressKeyCombination(int... keyCodes) {
        for (int keyCode : keyCodes) {
            robot.keyPress(keyCode);
        }
        for (int keyCode : keyCodes) {
            robot.keyRelease(keyCode);
        }
    }

    @Override
    public void delay(int millis) {
        robot.delay(millis);
    }
}